char *address;
int port;
+ char *ssl_cert;
+ char *ssl_key;
GSocketService *service;
BroadwayOutput *output;
guint32 id_counter;
typedef struct HttpRequest {
BroadwayServer *server;
- GSocketConnection *connection;
+ GSocketConnection *socket_connection;
+ GIOStream *connection;
GDataInputStream *data;
GString *request;
} HttpRequest;
struct BroadwayInput {
BroadwayServer *server;
BroadwayOutput *output;
- GSocketConnection *connection;
+ GIOStream *connection;
GByteArray *buffer;
GSource *source;
gboolean seen_time;
BroadwayServer *server = BROADWAY_SERVER (object);
g_free (server->address);
+ g_free (server->ssl_cert);
+ g_free (server->ssl_key);
G_OBJECT_CLASS (broadway_server_parent_class)->finalize (object);
}
static void
http_request_free (HttpRequest *request)
{
+ g_object_unref (request->socket_connection);
g_object_unref (request->connection);
g_object_unref (request->data);
g_string_free (request->request, TRUE);
GInputStream *in;
gssize res;
guint8 buffer[1024];
- GError *error;
+ GError *error = NULL;
if (input == NULL)
return;
- in = g_io_stream_get_input_stream (G_IO_STREAM (input->connection));
+ in = g_io_stream_get_input_stream (input->connection);
- error = NULL;
res = g_pollable_input_stream_read_nonblocking (G_POLLABLE_INPUT_STREAM (in),
buffer, sizeof (buffer), NULL, &error);
/* Not found, read more, blocking */
- in = g_io_stream_get_input_stream (G_IO_STREAM (input->connection));
+ in = g_io_stream_get_input_stream (input->connection);
+
res = g_input_stream_read (in, buffer, sizeof (buffer), NULL, NULL);
if (res <= 0)
return NULL;
error_code, reason,
error_code, reason,
reason);
+
/* TODO: This should really be async */
- g_output_stream_write_all (g_io_stream_get_output_stream (G_IO_STREAM (request->connection)),
- res, strlen (res), NULL, NULL, NULL);
+ g_output_stream_write_all (g_io_stream_get_output_stream (request->connection),
+ res, strlen (res), NULL, NULL, NULL);
+
g_free (res);
http_request_free (request);
}
g_print ("v7 proto response:\n%s", res);
#endif
- g_output_stream_write_all (g_io_stream_get_output_stream (G_IO_STREAM (request->connection)),
- res, strlen (res), NULL, NULL, NULL);
+ g_output_stream_write_all (g_io_stream_get_output_stream (request->connection),
+ res, strlen (res), NULL, NULL, NULL);
g_free (res);
}
else
return;
}
- socket = g_socket_connection_get_socket (request->connection);
+ socket = g_socket_connection_get_socket (request->socket_connection);
setsockopt (g_socket_get_fd (socket), IPPROTO_TCP,
TCP_NODELAY, (char *) &flag, sizeof(int));
g_byte_array_append (input->buffer, data_buffer, data_buffer_size);
input->output =
- broadway_output_new (g_io_stream_get_output_stream (G_IO_STREAM (request->connection)), 0);
+ broadway_output_new (g_io_stream_get_output_stream (request->connection), 0);
/* This will free and close the data input stream, but we got all the buffered content already */
http_request_free (request);
- in = g_io_stream_get_input_stream (G_IO_STREAM (input->connection));
+ in = g_io_stream_get_input_stream (input->connection);
+
input->source = g_pollable_input_stream_create_source (G_POLLABLE_INPUT_STREAM (in), NULL);
g_source_set_callback (input->source, (GSourceFunc)input_data_cb, input, NULL);
g_source_attach (input->source, NULL);
"Content-Length: %"G_GSIZE_FORMAT"\r\n"
"\r\n",
mimetype, len);
+
/* TODO: This should really be async */
- g_output_stream_write_all (g_io_stream_get_output_stream (G_IO_STREAM (request->connection)),
+ g_output_stream_write_all (g_io_stream_get_output_stream (request->connection),
res, strlen (res), NULL, NULL, NULL);
g_free (res);
- g_output_stream_write_all (g_io_stream_get_output_stream (G_IO_STREAM (request->connection)),
+ g_output_stream_write_all (g_io_stream_get_output_stream (request->connection),
data, len, NULL, NULL, NULL);
http_request_free (request);
}
GInputStream *in;
request = g_new0 (HttpRequest, 1);
- request->connection = g_object_ref (connection);
+ request->socket_connection = g_object_ref (connection);
request->server = BROADWAY_SERVER (source_object);
request->request = g_string_new ("");
- in = g_io_stream_get_input_stream (G_IO_STREAM (connection));
+ if (request->server->ssl_cert && request->server->ssl_key)
+ {
+ GError *error = NULL;
+ GTlsCertificate *certificate;
+
+ certificate = g_tls_certificate_new_from_files (request->server->ssl_cert,
+ request->server->ssl_key,
+ &error);
+ if (!certificate)
+ {
+ g_warning ("Cannot create TLS certificate: %s", error->message);
+ g_error_free (error);
+ return FALSE;
+ }
+
+ request->connection = g_tls_server_connection_new (G_IO_STREAM (connection),
+ certificate,
+ &error);
+ if (!request->connection)
+ {
+ g_warning ("Cannot create TLS connection: %s", error->message);
+ g_error_free (error);
+ return FALSE;
+ }
+
+ if (!g_tls_connection_handshake (G_TLS_CONNECTION (request->connection),
+ NULL, &error))
+ {
+ g_warning ("Cannot create TLS connection: %s", error->message);
+ g_error_free (error);
+ return FALSE;
+ }
+ }
+ else
+ {
+ request->connection = g_object_ref (connection);
+ }
+
+ in = g_io_stream_get_input_stream (request->connection);
request->data = g_data_input_stream_new (in);
g_filter_input_stream_set_close_base_stream (G_FILTER_INPUT_STREAM (request->data), FALSE);
}
BroadwayServer *
-broadway_server_new (char *address, int port, GError **error)
+broadway_server_new (char *address,
+ int port,
+ const char *ssl_cert,
+ const char *ssl_key,
+ GError **error)
{
BroadwayServer *server;
GInetAddress *inet_address;
server = g_object_new (BROADWAY_TYPE_SERVER, NULL);
server->port = port;
server->address = g_strdup (address);
+ server->ssl_cert = g_strdup (ssl_cert);
+ server->ssl_key = g_strdup (ssl_key);
if (address == NULL)
{